package code;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import labeling.Labeling;
import math.RMSE;
import model.MF;

import org.apache.commons.math3.stat.inference.TTest;

import data.Data;
import file.Parser;

public class TenFoldCrossValidation_IdealModel {

	/**
	 * @param args
	 */
	public static void main(String[] args) throws IOException {
		double[] mfRMSE = new double[5];
		double[] smfRMSE = new double[5];
		
		for(int iter=0; iter<5; iter++){
			System.out.println("Iteration: "+iter);
			String dir = "D:\\Netflix Dataset\\download\\test"+(iter+1);
			Parser testParser = new Parser(dir);
			List<Data> test = testParser.getList();
			double avgTest = testParser.getAvg();
			
			System.out.println("Number of ratings in test: "+test.size());
			System.out.println("Avg. ratings in test: "+avgTest);

			String dirTrain = "D:\\Netflix Dataset\\download\\train"+(iter+1);
			Parser trainParser = new Parser(dirTrain);
			List<Data> train = trainParser.getList();
			
			System.out.println("Number of ratings in train: "+train.size());
			
			double sumTrain = 0.0;
			for(Data data : train){
				byte rat = data.rat;
				sumTrain += rat;
			}			
			
			double avgTrain = sumTrain/train.size();
			System.out.println("Avg. rating in train: "+avgTrain);
			
			int nrat = train.size();
			int nuser = 93705;
			int maxuid = 95526;
			int nitem = 3561;
			
			int k = 5;
			double gamma = 0.02;
			double lambda = 0.02;
			
			System.out.println("k: "+k);
			System.out.println("lambda: "+lambda);
			System.out.println("gamma: "+gamma);
			
			double[] ufactor = new double[maxuid * k];
			double[] ifactor = new double[nitem * k];				
			double[] ubias = new double[maxuid];
			double[] ibias = new double[nitem];
			
			MF mf = new MF(k, gamma, lambda, train);

			ubias = mf.getUbias();
			ibias = mf.getIbias();
			ufactor = mf.getUfactor();
			ifactor = mf.getIfactor();

			System.out.println();
			System.out.println("MF model's test RMSE: " + RMSE.RMSE(test, avgTest, ubias, ibias, ufactor, ifactor, k));
			mfRMSE[iter] = RMSE.RMSE(test, avgTest, ubias, ibias, ufactor, ifactor, k);
			System.out.println();
			
			List<Data> postrain = new ArrayList<Data>();
			List<Data> negtrain = new ArrayList<Data>();

			Labeling labelTrain = new Labeling(train, avgTrain, ubias, ibias);
			postrain = labelTrain.getPos();
			negtrain = labelTrain.getNeg();
			
			System.out.println("Number of pos. ratings in train: "+postrain.size());
			System.out.println("Number of neg. ratings in train: "+negtrain.size());
			System.out.println("Percentage of pos. ratings in train: "+postrain.size()/(double)train.size());
			System.out.println("Percentage of neg. ratings in train: "+negtrain.size()/(double)train.size());
			
			double[] uposbias = new double[maxuid];
			double[] iposbias = new double[nitem];			
			double[] uposfactor = new double[maxuid];
			double[] iposfactor = new double[nitem];
			
			MF pmf = new MF(k, gamma, lambda, postrain);

			uposbias = pmf.getUbias();
			iposbias = pmf.getIbias();
			uposfactor = pmf.getUfactor();
			iposfactor = pmf.getIfactor();
			double avgpos = pmf.getAvgTrain();
			
			double[] unegbias = new double[maxuid];
			double[] inegbias = new double[nitem];
			double[] unegfactor = new double[maxuid];
			double[] inegfactor = new double[nitem];
			
			MF nmf = new MF(k, gamma, lambda, negtrain);

			unegbias = nmf.getUbias();
			inegbias = nmf.getIbias();
			unegfactor = nmf.getUfactor();
			inegfactor = nmf.getIfactor();
			double avgneg = nmf.getAvgTrain();
			
			List<Data> postest = new ArrayList<Data>();
			List<Data> negtest = new ArrayList<Data>();
			
			Labeling labelTest = new Labeling(test, avgTrain, ubias, ibias);
			postest = labelTest.getPos();
			negtest = labelTest.getNeg();

			System.out.println();
			System.out.println("SMF model's test RMSE: " + RMSE.RMSE(postest, negtest, avgpos, avgneg, uposbias, iposbias, uposfactor, iposfactor, unegbias, inegbias, unegfactor, inegfactor, k));
			smfRMSE[iter] = RMSE.RMSE(postest, negtest, avgpos, avgneg, uposbias, iposbias, uposfactor, iposfactor, unegbias, inegbias, unegfactor, inegfactor, k);
			System.out.println();
		};
		
		TTest tTest = new TTest();
		System.out.println("t statistics: "+tTest.pairedT(mfRMSE, smfRMSE));
		System.out.println("p-value for t test: "+tTest.pairedTTest(mfRMSE, smfRMSE));

	}

}
